/*
* ============================================================================
*  Name        : sea_platform_posix.cpp
*  Part of     : Finite state machine framework 
*  Description : 
*  Version     : %version: %
*  
*
* ============================================================================
*/

#include "sea_platform.h"
#include "sea_trace.h"

/**
 * @file sea_platform_posix.cpp
 *
 * @ingroup Platforms
 */
using namespace sea;

// -------------------------------------------------------------------------------------------------
// Resume the thread
// -------------------------------------------------------------------------------------------------
void OsThread::start( ) 
{ 
    if ( m_started )
    {
        return;
    }

    if ( pthread_create( &m_thread, 0, &OsThread::entry, this ) != 0 )
    {
        ASSERT_DEBUG( false );
    }
    else
    {
        m_started = true;
    }
}

// -------------------------------------------------------------------------------------------------
// Wait for the thread to finish
// -------------------------------------------------------------------------------------------------
void OsThread::wait( i::uint32 time /* = -1 */ )
{
    SEA_UNUSED( time );
    if ( m_started )
    {
        if ( m_thread && pthread_join( m_thread, 0 ) != 0 )
        {
            ASSERT_DEBUG( false );
        }
        m_started = false;
    }
}

// -------------------------------------------------------------------------------------------------
// Trace function
// -------------------------------------------------------------------------------------------------
int Trace::Print( const char* format_str, ... )
{
    static OsMutex traceLock;
    OsMutex::Scoped safe( &traceLock );

    int result = -1;
    char buffer[ MAX_BUFFER ];

    time_t raw_time;
    struct tm time;
    ::time( &raw_time );
    localtime_r( &raw_time, &time );
    
    struct timeval tv;
    struct timezone tz;
    gettimeofday( &tv, &tz );

    sprintf( buffer, "%02u:%02u:%02u.%03u ", time.tm_hour, time.tm_min, time.tm_sec, ( i::uint32 )( tv.tv_usec / 1000 ) );

    va_list arg_list;
    va_start( arg_list, format_str );
    result = vsprintf( buffer + 13, format_str, arg_list );
    va_end( arg_list );

    std::cout << buffer << std::endl;

    return result;
}


// -------------------------------------------------------------------------------------------------
// fopen_s substitude in Linux
// -------------------------------------------------------------------------------------------------
int sea::fopen_s( FILE** file, const char *file_name, const char *mode )
{
    if ( file == NULL )
    {
        return -1;
    }

    *file = fopen( file_name, mode );
    if ( *file == NULL )
    {
        return -1;
    }
    return 0;
}
